import * as d3 from 'd3'
import { loadLiquidFillGauge, liquidFillGaugeDefaultSettings } from '@/assets/js/geoMap/D3-Liquid-Fill-Gauge.js'
import { WindGauge } from '@/assets/js/geoMap/WindGauge.js'

export class CityComparison {
  minRadius = '0%'
  maxRadius = '100%'
  chart = {}
  basicRadius = 0
  color = d3.scaleOrdinal(d3.schemeCategory10)

  constructor(config) {
    this.cityName = config.name
    this.chart.svg = config.container
    this.position = config.position
    this.basicRadius = config.basicRadius

    this.pollutantData = config.pollutantData
    this.tempData = config.tempData
    this.rh = config.rh
    this.wind = config.wind
    this.psfcData = config.psfcData
  }

  draw() {
    this.initLayout()
    this.drawchart()
  }
  update(config) {
    this.basicRadius = config.basicRadius
    let maxRadius = this.basicRadius * parseFloat(this.maxRadius.split('%')).toFixed(1) / 100
    let minRadius = this.basicRadius * parseFloat(this.minRadius.split('%')).toFixed(1) / 100
    this.position = config.position
    this._position = [(config.position[0] - this.position[0]), (config.position[1] - this.position[1])]
    this._zoom = config.zoom
    this.chart.rScale.range([minRadius + 10, maxRadius])
    this.chart.arc.outerRadius(d => this.chart.rScale(Math.abs(d.data.value)))

    this.chart.basicArc.outerRadius(maxRadius)

    this.chart.psfcArc.outerRadius(maxRadius + 1)
    this.drawchart()
  }

  initLayout() {
    this.pollutantData.map(d => {
      d.angle = 1
    })

    let maxRadius = this.basicRadius * parseFloat(this.maxRadius.split('%')).toFixed(1) / 100
    let minRadius = this.basicRadius * parseFloat(this.minRadius.split('%')).toFixed(1) / 100

    this.chart.pie = d3.pie()
      .sort(null)
      .value(d => d.angle)
      .startAngle(-Math.PI / 2)
      .endAngle(Math.PI / 2)
      .padAngle(1e-2)

    this.chart.rScale = d3.scaleLinear()
      .domain([0, 500])
      .range([minRadius + 10, maxRadius])
    // 污染物数据
    this.chart.arc = d3.arc()
      .innerRadius(minRadius)
      .outerRadius(d => this.chart.rScale(Math.abs(d.data.value)))
    // 污染物最大值
    this.chart.basicArc = d3.arc()
      .innerRadius(minRadius)
      .outerRadius(maxRadius)

    this.chart.psfcArc = d3.arc()
      .innerRadius(maxRadius)
      .outerRadius(maxRadius + 5)
  }

  drawchart() {
    let arc = this.chart.arc
    let basicArc = this.chart.basicArc
    let psfcArc = this.chart.psfcArc
    let pieData = this.chart.pie(this.pollutantData)

    let pollutantConfig = {
      'arc': arc,
      'basicArc': basicArc,
      'data': pieData,
      'className': 'arc',
      'basicBackground': '#FAFBFC',
      'fillFunc': function(d) {
        var mainpollution = ['PM2.5', 'PM10', 'SO2', 'NO2', 'CO', 'O3']
        var pollutioncolor = ['#deb89e', '#997c61', '#7b6b57', '#654047', '#3e3123', '#c1888c']
        // console.log(d)
        return pollutioncolor[mainpollution.indexOf(d.data.name.split('(')[0])]
      }
    }
    let psfcData = [{
      'data': {
        'name': 'PSFC',
        'value': this.psfcData.value
      },
      'index': 0,
      'value': 1,
      'startAngle': -(Math.PI / 2),
      'endAngle': -(Math.PI / 2) + Math.PI * (this.psfcData.value / this.psfcData.max)
    }]
    let psfcConfig = {
      'arc': psfcArc,
      'basicArc': psfcArc,
      'data': psfcData,
      'className': 'arc',
      'basicBackground': '#FAFBFC',
      'fillFunc': function(d) {
        return '#98dcf3'
      }
    }

    this.renderPollutant(pollutantConfig)
    this.renderPollutant(psfcConfig)
    this.renderTEMP()
    this.renderRH()
    this.renderWind(this.wind)

    // let lastIndex = 'PM10(微克每立方米)'
    // let thisIndex = 'PM2.5(微克每立方米)'
    // let direction = []
    // for (let i = 0; i < pieData.length; ++i) {
    //   if (pieData[i].data.name === lastIndex) {
    //     direction[0] = (pieData[i].endAngle - pieData[i].startAngle) / 2 + pieData[i].startAngle
    //   }
    //   if (pieData[i].data.name === thisIndex) {
    //     direction[1] = (pieData[i].endAngle - pieData[i].startAngle) / 2 + pieData[i].startAngle
    //   }
    // }
    // let midPoint = [this.position[0], this.position[1]]
    // let groupTransfer = this.chart.svg.append('g')
    //   .attr('class', 'pollutionTransfer')
    // let transferConfig = {
    //   'maxRadius': this.basicRadius * parseFloat(this.maxRadius.split('%')).toFixed(1) / 100 / 2,
    //   'container': groupTransfer,
    //   'midPoint': midPoint,
    //   'direction': direction
    // }

    // this.renderTransfer(transferConfig)
  }

  renderPollutant(config) {
    let arcs = this.chart.svg.selectAll('.' + config.className)
      .data(config.data, d => d.data.name)

    let exitT = d3.transition()
      .duration(1000)

    let t = d3.transition(exitT)

    // let enterT = d3.transition(t)

    arcs.select('path.data-arc')
      .transition(t)
      .attr('transform', () => {
        if (this._position === undefined) {
          return 'translate(' + (this.position[0]) + ',' +
            this.position[1] + ')'
        } else {
          return 'translate(' + (this._position[0]) + ',' +
            this._position[1] + ')'
        }
      })
      .attrTween('d', dataArcTween)

    arcs.select('path.basic-arc')
      .transition(t)
      .attr('transform', () => {
        return 'translate(' + (this.position[0]) + ',' +
          this.position[1] + ')'
      })
      .attrTween('d', basicArcTween)

    arcs.select('text')
      .transition(t)
      .attr('transform', d => 'translate(' + this.chart.arc.centroid(d) + ')')

    let arcEnter = arcs.enter()
      .append('g')
      .attr('class', 'arc')
      .attr('transform', () => {
        if (this._position === undefined) {
          return 'translate(' + (this.position[0]) + ',' +
            this.position[1] + ')'
        } else {
          return 'translate(' + (this._position[0]) + ',' +
            this._position[1] + ')'
        }
      })

    arcEnter.append('path')
      .attr('d', d => config.basicArc({
        data: JSON.parse(JSON.stringify(d.data)),
        startAngle: d.startAngle,
        endAngle: d.startAngle
      }))
      .attr('class', 'basic-arc')
      .style('fill', '#FAFBFC')
      .style('stroke', 'black')
      .style('stroke-width', 1)
      .style('opacity', 0.5)
      .each(function(d) {
        this._current = {
          data: JSON.parse(JSON.stringify(d.data)),
          startAngle: d.startAngle,
          endAngle: d.startAngle
        }
      })

    arcEnter.append('path')
      .attr('d', (d, i) => config.arc({
        data: JSON.parse(JSON.stringify(d.data)),
        startAngle: d.startAngle,
        endAngle: d.startAngle
      }))
      .attr('class', 'data-arc')
      .style('fill', d => {
        return config.fillFunc(d)
      })
      .each(function(d) {
        this._current = {
          data: JSON.parse(JSON.stringify(d.data)),
          startAngle: d.startAngle,
          endAngle: d.startAngle
        }
      })
    // console.log(arcEnter.select('path.data-arc'))
    arcEnter.select('path.data-arc')
      .transition()
      .duration(750)
      .attrTween('d', dataArcTween)

    arcEnter.select('path.basic-arc')
      .transition()
      .duration(750)
      .attrTween('d', basicArcTween)

    function dataArcTween(a) {
      var i = d3.interpolate(this._current, a)
      this._current = i(0)
      return function(t) {
        return config.arc(i(t))
      }
    }

    function basicArcTween(a) {
      var i = d3.interpolate(this._current, a)
      this._current = i(0)
      return function(t) {
        return config.basicArc(i(t))
      }
    }
  }

  renderTEMP() {
    let maxRadius = this.basicRadius * parseFloat(this.maxRadius.split('%')).toFixed(1) / 100
    let height = maxRadius * 0.5
    let dataHeigth = height * this.tempData.value
    let width = 10

    let tempRect = this.chart.svg.selectAll('.temp')
      .data([this.tempData])

    let tempEnter = tempRect.enter()
      .append('g')
      .attr('class', 'temp')

    tempEnter.append('rect')
      .attr('x', this.position[0] - width * 0.5)
      .attr('y', this.position[1] + height)
      .attr('width', width)
      .attr('height', 0)
      .attr('class', 'basic-rect')
      .style('stroke', 'black')
      .style('stroke-width', 1)
      .style('fill', '#FAFBFC')

    tempEnter.select('.basic-rect')
      .transition()
      .duration(1000)
      .attr('y', this.position[1])
      .attr('width', width)
      .attr('height', height)

    tempEnter.append('rect')
      .attr('x', this.position[0] - width * 0.5)
      .attr('y', this.position[1] + height)
      .attr('width', width)
      .attr('height', 0)
      .attr('class', 'data-rect')
      .style('stroke', 'black')
      .style('stroke-width', 1)
      .style('fill', '#fb570b')

    tempEnter.select('.data-rect')
      .transition()
      .duration(1000)
      .attr('y', this.position[1] + (height - dataHeigth))
      .attr('width', width)
      .attr('height', dataHeigth)
  }

  renderRH() {
    this.chart.svg.append('g')
      .attr('id', 'liquid-fill-gauge')
    let maxRadius = this.basicRadius * parseFloat(this.maxRadius.split('%')).toFixed(1) / 100
    let height = maxRadius * 0.5
    let config1 = liquidFillGaugeDefaultSettings()
    config1.circleThickness = 0.2
    config1.textVertPosition = 0.2
    config1.textSize = 0.7
    config1.circleThickness = 0.1
    config1.waveAnimateTime = 0
    config1.waveHeight = 0.1
    config1.waveCount = 1
    config1.width = height
    config1.height = height
    config1.waveColor = '#fce37e'
    config1.locationX = this.position[0] - height / 2
    config1.locationY = this.position[1] + height
    loadLiquidFillGauge('liquid-fill-gauge', this.rh, config1)
  }

  renderWind(wind) {
    let maxRadius = this.basicRadius * parseFloat(this.maxRadius.split('%')).toFixed(1) / 100 * 1.2
    let height = maxRadius * Math.tan(Math.PI / 16)

    let direction = (Math.floor(wind[0]['windDirection'] / 22.5) * 22.5) * Math.PI / 180
    let group = this.chart.svg.append('g')
      .attr('class', 'gWind')
    let gWind = group.append('g')
      .attr('id', 'wind-gauge')

    let config1 = {
      'elementId': gWind,
      'data': wind[0].windSpeed,
      'innerRadius': height * 0.8,
      'outerRadius': height,
      'positionX': this.position[0] + maxRadius * Math.sin(direction),
      'positionY': this.position[1] - maxRadius * Math.cos(direction)
    }

    this.renderSingleWind(config1)

    // let sDirection = (Math.floor(wind[1]['windDirection'] / 22.5) * 22.5) * Math.PI / 180
    // let gWind2 = group.append('g')
    //   .attr('id', 'wind-gauge2')

    // let config2 = {
    //   'elementId': gWind2,
    //   'data': wind[1].windSpeed,
    //   'innerRadius': height * 0.8,
    //   'outerRadius': height,
    //   'positionX': this.position[0] + maxRadius * Math.sin(sDirection),
    //   'positionY': this.position[1] - maxRadius * Math.cos(sDirection)
    // }

    // this.renderSingleWind(config2)

    // let transferConfig = {
    //   'maxRadius': maxRadius,
    //   'container': group,
    //   'midPoint': this.position,
    //   'direction': [direction - Math.PI / 15, sDirection + Math.PI / 15]
    // }
    // this.renderTransfer(transferConfig)
  }

  renderSingleWind(config) {
    let windChart = new WindGauge()
    windChart.data = config.data
    windChart.innerRadius = config.innerRadius
    windChart.outerRadius = config.outerRadius
    windChart.positionX = config.positionX
    windChart.positionY = config.positionY
    windChart.initLayout(config.elementId)
    windChart.initGauge()
    windChart.update()
  }

  renderTransfer(config) {
    let arc = d3.arc()
      .innerRadius(config.maxRadius - 2)
      .outerRadius(config.maxRadius)

    this.chart.svg.append('svg:defs')
      .append('svg:marker')
      .attr('id', 'arrow')
      .attr('refX', 6)
      .attr('refY', 3)
      .attr('markerWidth', 30)
      .attr('markerHeight', 30)
      .attr('orient', 'auto')
      .attr('markerUnits', 'userSpaceOnUse')
      .append('path')
      .attr('d', 'M 0 0 6 3 0 6 1.5 3')
      .style('stroke-width', 1)
      .style('stroke', 'black')

    let transferLine = config.container.selectAll('.transferLine')
      .data([{
        'startAngle': config.direction[0],
        'endAngle': config.direction[0]
      }])
      .enter()
      .append('path')
      .attr('class', 'transferLine')
      .attr('transform', 'translate(' + config.midPoint[0] + ',' + config.midPoint[1] + ')')
      .attr('d', function(d) {
        let path = arc(d).split('L')[0]
        return path
      })
      .style('fill', 'none')
      .style('stroke', 'blue')
      .style('stroke-width', 2)
      .each(function(d) {
        this._current = d
      })

    transferLine
      .data([{
        'startAngle': config.direction[0],
        'endAngle': config.direction[1]
      }])
      .transition()
      .duration(1000)
      .style('marker-end', 'url(#arrow)')
      .attrTween('d', arcTween)

    function arcTween(a) {
      var i = d3.interpolate(this._current, a)
      this._current = i(0)
      return function(t) {
        return arc(i(t)).split('L')[0]
      }
    }
  }
}
